package com.generic.action.member;

import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.servlet.ServletContext;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.InterceptorRefs;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.util.ServletContextAware;

import com.generic.dao.impl.ImageDao;
import com.generic.ds.HibernateSession;
import com.generic.module.impl.Image;
import com.generic.module.impl.Member;
import com.generic.util.Constant;
import com.generic.util.FileUtil;
import com.generic.util.GraphicsUtil;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

@Namespace("/member")
@ParentPackage("member")
@InterceptorRefs({
	@InterceptorRef("authorizationStack")	
})
public class Uploader extends ActionSupport implements ServletContextAware {
	private static final Log log = LogFactory.getLog(Uploader.class);
	private static final long serialVersionUID = -4149403212439528824L;
	private ServletContext servletContext;
	private File[] uploads;
	private String[] uploadsFileName;
	private String[] uploadsContentType;
	private String[] tempFilePaths;
	private Integer x;
	private Integer y;
	private Integer w;
	private Integer h;
	
	public Integer getX() {
		return x;
	}

	public void setX(Integer x) {
		this.x = x;
	}

	public Integer getY() {
		return y;
	}

	public void setY(Integer y) {
		this.y = y;
	}

	public Integer getW() {
		return w;
	}

	public void setW(Integer w) {
		this.w = w;
	}

	public Integer getH() {
		return h;
	}

	public void setH(Integer h) {
		this.h = h;
	}

	public File[] getUploads() {
		return uploads;
	}

	public void setUploads(File[] uploads) {
		this.uploads = uploads;
	}

	public String[] getUploadsFileName() {
		return uploadsFileName;
	}

	public void setUploadsFileName(String[] uploadsFileName) {
		this.uploadsFileName = uploadsFileName;
	}

	public String[] getUploadsContentType() {
		return uploadsContentType;
	}

	public void setUploadsContentType(String[] uploadsContentType) {
		this.uploadsContentType = uploadsContentType;
	}

	public String[] getTempFilePaths() {
		return tempFilePaths;
	}

	public void setTempFilePaths(String[] tempFilePaths) {
		this.tempFilePaths = tempFilePaths;
	}

	@Override
	public void setServletContext(ServletContext context) {
		this.servletContext = context;
	}
	
	public String execute() {		
		return SUCCESS;
	}
	
	@Action(value = "uploader-pre-photo", results = {
		    @Result(name = "success", location = "uploader-pre-photo.jsp")})
	public String uploaderPrePhoto() {
		Map<String, Object> session = ActionContext.getContext().getSession();
		Member member = (Member)session.get(Constant.SESSION_MEMBER);
		Long memberId = member.getId();
		
		File filePath = new File(servletContext.getRealPath("/") + Constant.IMAGE_TEMP + memberId);
		if(filePath.exists()) {
			FileUtil.deleteDirectory(filePath);
		}
		filePath.mkdirs();
		
		return SUCCESS;
	}
	
	/**
	 * Resizes and saves the photo to a temporary folder
	 * @return Action result
	 */
	@Action(value = "uploader-post-photo",
		interceptorRefs=@InterceptorRef(value="fileUpload",params={"allowedTypes","image/jpeg,image/gif,image/png"}),
		results = {
			@Result(name = "input", location = "uploader-post-photo.jsp"),
		    @Result(name = "success", type="redirectAction", params= {"actionName","photo","namespace","/member"}) })
	public String uploaderPostPhoto() {
		String result = SUCCESS;
		tempFilePaths = new String[uploads.length];
		Map<String, Object> session = ActionContext.getContext().getSession();
		Member member = (Member)session.get(Constant.SESSION_MEMBER);
		Long memberId = member.getId();
		try {
			File filePath = new File(servletContext.getRealPath("/") + Constant.IMAGE_TEMP + memberId);
			
			for (int i = 0; i < uploads.length; i++) {				
				File fileToCreate = new File(filePath, uploadsFileName[i]);
				String fileExtension = uploadsFileName[i].substring(uploadsFileName[i].lastIndexOf(".")+1);
				BufferedImage img = ImageIO.read(uploads[i]);
				BufferedImage bi = GraphicsUtil.getStandardSize(img);
				ImageIO.write(bi, fileExtension, fileToCreate);
				tempFilePaths[i] = Constant.IMAGE_TEMP+memberId+"/"+uploadsFileName[i];
			}
		} catch (Exception e) {
			log.equals(e);			
			addActionError(e.getMessage());
			result = INPUT;
		}
		return result;
	}
	
	@Action(value="profile-photo-save", 
			results = {
			@Result(name = "input", location = "member/profile-photo-add.jsp"),
		    @Result(name = "success", type="redirectAction", params={"actionName","profile-photo-add.jsp","namespace","/member"}) })
	public String photoSave() {
		
		Map<String, Object> session = ActionContext.getContext().getSession();
		Member member = (Member)session.get(Constant.SESSION_MEMBER);
		Long memberId = member.getId();
		
		HibernateSession hs = new HibernateSession();
		try {
			hs.beginTransaction();
			ImageDao imageDao = new ImageDao(hs);
			
			// Create directory folder for the image file 
			String dirPath = Constant.IMAGE_PATH + memberId;
			File filePath = new File(servletContext.getRealPath("/") + dirPath);
			filePath.mkdirs();
			
			// Create directory folder for the image thumbnail 
			dirPath = Constant.IMAGE_THUMB_PATH + memberId;
			File filePath2 = new File(servletContext.getRealPath("/") + dirPath);
			filePath2.mkdirs();
			
			Long seq = imageDao.getMaxId(memberId);
			String fileExtension = tempFilePaths[0].substring(tempFilePaths[0].lastIndexOf(".")+1);
			String fileName = seq++ + "." + fileExtension;
			File file = new File(filePath, fileName);
			if (!file.exists()) {
				File fileSrc = new File(servletContext.getRealPath("/")+Constant.FILE_SEPARATOR+tempFilePaths[0]);
				
				// Save image 
				FileUtils.copyFile(fileSrc, file);
				
				// Save image thumbnail 
				BufferedImage img = ImageIO.read(fileSrc);
				file = new File(filePath2, fileName);
				BufferedImage bi = GraphicsUtil.getThumbnailSize(img);
				ImageIO.write(bi, fileExtension, file);				
				
				// Save image profile
//				file = new File(filePath2, fileName);
//				bi = GraphicsUtil.getProfileSize(img.getSubimage(x,y,w,h));
//				ImageIO.write(bi, fileExtension, file);
				
				// Save image meta data into database 
				Image image = new Image();
				image.setProfileId(memberId);
				image.setFileName(fileName);
				imageDao.insertOrUpdate(image);
			}
				
			// Set first image as the default image if it hasn't been set 
//			if(member.getImageId() == null) {
//				Long imageId = imageDao.getMinId(memberId);
//				MemberDao memberDao = new MemberDao(hs);
//				memberDao.setDefaultImage(memberId, imageId);
//				member.setImageId(imageId);
//				memberDao.insertOrUpdate(member);
//			}			
			
			hs.commitTransaction();
		} catch (Exception e) {
			hs.rollbackTransaction(e);
		} finally {
			hs.closeSession();
		}

		return SUCCESS;
	}
}
